﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using haglazMedia.Base.Logging;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;

namespace sdc4.IpScanner
{
    public partial class frmMain : Form
    {
        private Network _NetWork = null;
        private NetworkInterface[] _Inf = null;
        private bool _StopScan = false; 

        public frmMain()
        {
            try
            {
                InitializeComponent();
            
            }
            catch (Exception ex)
            {
                MessageHandler.ShowCustomErrorDialog(this.name + "->frmMain", ex);
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            try
            {
                this.Text = "Network - IpScanner [" + Environment.UserName + "] - [" + ProductVersion + "]";
                _NetWork = new Network();
                FillInterfaces();
                LoadSettings();
            }
            catch (Exception ex)
            {
                MessageHandler.ShowCustomErrorDialog(this.name + MethodBase.GetCurrentMethod().Name , ex);
            }   
        }


        private void FillInterfaces()
        {
            _Inf = _NetWork.GetInterfaces();
            foreach (NetworkInterface curInf in _Inf)
            {
                string item = curInf.Name  + "|" + curInf.Id;
                cmbInterfaces.Items.Add(item);
                _NetWork.AddInterface(item, curInf);                
            }

            if (cmbInterfaces.Items.Count > 0) cmbInterfaces.SelectedIndex = 0;
        }

        private void SaveSettings()
        {

            try
            {
                if (cmbInterfaces.SelectedItem != null)
                    Properties.Settings.Default.network_interface = cmbInterfaces.SelectedItem.ToString();

                Properties.Settings.Default.ping_timeout = (int)numTimeOut.Value;
                Properties.Settings.Default.Save();
            }
            catch (Exception ex)
            {
                MessageHandler.ShowCustomErrorDialog(this.name + MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        public void LoadSettings()
        {
            try
            {
                cmbInterfaces.SelectedItem = Properties.Settings.Default.network_interface;
                numTimeOut.Value = Properties.Settings.Default.ping_timeout > 0 ? Properties.Settings.Default.ping_timeout : 15;
                this.SetInterfaceDetails(cmbInterfaces.SelectedItem.ToString());
            }
            catch (Exception ex)
            {
               MessageHandler.ShowCustomErrorDialog(this.name + MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            SaveSettings();
        }

        private void cmbInterfaces_SelectionChangeCommitted(object sender, EventArgs e)
        {   
            if (cmbInterfaces.SelectedItem == null) return;
            this.SetInterfaceDetails(cmbInterfaces.SelectedItem.ToString());   
        }

        private void SetInterfaceDetails(string pIf)
        {
            List<IPAddressInformation> ipAddressInformation = new List<IPAddressInformation>(); 

            string[] details = _NetWork.GetInterfaceDetails((NetworkInterface)_NetWork.Interfaces[pIf], ref ipAddressInformation);

            lstInterfaceDetails.Items.Clear();

            if (details == null) return;

            for (int z = 0; z < details.Length; z++)
            {
                lstInterfaceDetails.Items.Add(details[z]);
            }

            txtIpFrom.Clear();
            txtIpTo.Clear();

            if (_NetWork.Ip == null) return;

            txtIpFrom.Text = _NetWork.Ip.ToString();
            txtIpTo.Text = _NetWork.Ip.ToString();
   

        }

        private void cmdScan_Click(object sender, EventArgs e)
        {
            try
            {
                cmdScan.Enabled = false;
                cmdStop.Visible = true;
                cmdStop.Enabled = true;
                prgMain.Visible = true;
                ExecutePing();
                _StopScan = false;
                prgMain.Value = 0;
                prgMain.Visible = false;
                cmdScan.Enabled = true;
                cmdStop.Visible = false;
                cmdStop.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageHandler.ShowCustomErrorDialog(this.ToString() + "->cmdScan_Click", ex);
            }

        

        }


        /// <summary>
        /// ExecutePing, executes the ping command
        /// with a loop for every digit.
        /// </summary>
        private void ExecutePing()
        {
            try
            {


                lvwHosts.Items.Clear();

                prgMain.Minimum = 0;

                Application.DoEvents();

                IPAddress ip = IPAddress.Parse(txtIpFrom.Text);
                IPAddress ip2 = IPAddress.Parse(txtIpTo.Text);
                IPAddress ipScan = null;
                string hostname = null;

                int[] aa = new int[4], bb = new int[4];

                //Get first, second, ... byte of address
                aa[0] = Convert.ToInt32(ip.GetAddressBytes()[0]);
                aa[1] = Convert.ToInt32(ip.GetAddressBytes()[1]);
                aa[2] = Convert.ToInt32(ip.GetAddressBytes()[2]);
                aa[3] = Convert.ToInt32(ip.GetAddressBytes()[3]);

                bb[0] = Convert.ToInt32(ip2.GetAddressBytes()[0]);
                bb[1] = Convert.ToInt32(ip2.GetAddressBytes()[1]);
                bb[2] = Convert.ToInt32(ip2.GetAddressBytes()[2]);
                bb[3] = Convert.ToInt32(ip2.GetAddressBytes()[3]);

                prgMain.Maximum = (bb[0] + bb[1] + bb[2] + bb[3]) - (aa[0] + aa[1] + aa[2] + aa[3]) + 1;

                for (int a = aa[0]; a <= bb[0]; a++)
                {
                    for (int b = aa[1]; b <= bb[1]; b++)
                    {
                        for (int c = aa[2]; c <= bb[2]; c++)
                        {
                            for (int d = aa[3]; d <= bb[3]; d++)
                            {
                                ipScan = IPAddress.Parse(a.ToString() + "." + b.ToString() + "." + c.ToString() + "." + d.ToString());

                                PingReply reply = _NetWork.SendPing(ipScan, (int)numTimeOut.Value);
                                hostname = null;
                                if (reply.Status == IPStatus.Success)
                                {
                                    hostname = chkGetName.Checked ? _NetWork.GetHostName(ipScan) : ipScan.ToString();
                                }
                                ListViewItem itm = new ListViewItem();
                                itm.Text = ipScan.ToString();

                                itm.SubItems.Add(hostname);
                                itm.SubItems.Add(reply.Status.ToString());
                                lvwHosts.Items.Add(itm);

                                lvwHosts.EnsureVisible(lvwHosts.Items.Count - 1);
                                prgMain.Increment(1);
                                Application.DoEvents();
                                if (_StopScan)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageHandler.ShowCustomErrorDialog(this.name + MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void cmdStop_Click(object sender, EventArgs e)
        {
            _StopScan = true;
        }

       
    }
}
